package com.budwk.app.sqfwV2.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.*;
import com.budwk.app.sqfw.services.*;
import com.budwk.app.sqfw.services.datamange.DataMangeCommunityService;
import com.budwk.app.sqfw.vo.GenerateExcelUrlVO;
import com.budwk.app.sqfwDoc.codeGenerator.impl.SqfwTemplatePdfCommonService;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.CompleteFlowPdfParamForController;
import com.budwk.app.sqfwDoc.codeGeneratorV2.pdfService.CompleteFlowCommonPdfService;
import com.budwk.app.sqfwDoc.dto.TemplateCodeUpdateDTO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.component.DocumentDownComponent;
import com.budwk.app.sqfwV2.component.OneFiveComponent;
import com.budwk.app.sqfwV2.component.SummarySafetyCommponent;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownExcelLedgerReqVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownFileTypesResVo;
import com.budwk.app.sqfwV2.dto.vo.SummaryQueryReqVo;
import com.budwk.app.sqfwV2.enums.FileServiceConfigEnum;
import com.budwk.app.sqfwV2.service.ShopsBaseInfoService;
import com.budwk.app.sqfwV2.service.SummarySafetyService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.util.DateUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.exception.BaseException;
import com.budwk.starter.common.page.Pagination;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.database.service.BaseServiceImpl;
import com.budwk.starter.security.utils.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.impl.FileSqlManager;
import org.nutz.dao.impl.NutDao;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@IocBean(args = {"refer:dao"})
@Slf4j
public class SummarySafetyServiceImpl extends BaseServiceImpl<Sqfw_formSummary_new> implements SummarySafetyService{
    public SummarySafetyServiceImpl(Dao dao) {
        super(dao);
        // 加载配置文件
        ((NutDao)dao).setSqlManager(new FileSqlManager("db/formSummary/formSummary.sql"));
    }

    @Inject
    private SummarySafetyCommponent summarySafetyCommponent;
    @Inject
    private SqfwCompleteflowService sqfwCompleteflowService;
    @Inject
    private SqfwFormSummaryPdfService sqfwFormSummaryPdfService;
    @Inject
    private SqfwFormsummaryNewService sqfwFormsummaryNewService;
    @Inject
    private ShopsBaseInfoService shopsBaseInfoService;
    @Inject
    private DataMangeCommunityService dataMangeCommunityService;
    @Inject
    private SqfwDownRecordlogService downRecordlogService;

    @Override
    public Sqfw_formSummary_new submitData(TemplateCodeUpdateDTO dto) {
        // 数据提交分类
        CompleteFlowCommonPdfService completeFlowCommonPdfService = summarySafetyCommponent.getCompleteFlowCommonPdfService(dto);
        if (completeFlowCommonPdfService == null) {
            SqfwTemplatePdfCommonService pdfCommonService = summarySafetyCommponent.getSqfwTemplatePdfCommonService(dto);
            if (pdfCommonService == null) {
                throw new AppException("数据异常，请检查source参数！");
            }
            // 创建一个任务
            summarySafetyCommponent.createOneTask(dto, null, dto.getFormSummary().getType());
            pdfCommonService.generatePdfAndMessage(SecurityUtil.getUserId(), dto);
            return dto.getFormSummary();
        }
        summarySafetyCommponent.createOneTask(dto, null, dto.getFormSummary().getType());
        completeFlowCommonPdfService.createPdfAndMsg(summarySafetyCommponent.buildSubmitParam(dto));
        return dto.getFormSummary();
    }

    @Override
    public Result<?> reGeneratePDF(String sqfwFlowId, String source) {
        // 1 组装基本参数
        TemplateCodeUpdateDTO dto = new TemplateCodeUpdateDTO();
        Sqfw_formSummary_new formSummary = new Sqfw_formSummary_new();
        Sqfw_completeflow completeflow = sqfwCompleteflowService.fetch(sqfwFlowId);
        formSummary.setType(completeflow.getFileType());
        dto.setFormSummary(formSummary);
        dto.setSource(source);

        if (DayingRoadPdfComponent.isDayYingSafeCity(completeflow.getUserId())) {
            dto.setSource(CommonConstants.DAYINGROAD);
        }
        // 2 业务数据提交
        CompleteFlowCommonPdfService completeFlowCommonPdfService = summarySafetyCommponent.getCompleteFlowCommonPdfService(dto);
        if (completeFlowCommonPdfService == null) {
            // 2.0数据
            SqfwTemplatePdfCommonService pdfCommonService = summarySafetyCommponent.getSqfwTemplatePdfCommonService(dto);
            if (pdfCommonService == null) {
                throw new AppException("数据异常，请检查source参数！");
            }
            pdfCommonService.reGeneratePDF(sqfwFlowId);
            return Result.success();
        }
        CompleteFlowPdfParamForController param = new CompleteFlowPdfParamForController();
        param.setCompleteFlowId(sqfwFlowId);
        // 3 生成pdf
        completeFlowCommonPdfService.reCreatePdfAndMsg(param);
        return Result.success();
    }

    @Override
    public Result<List<GenerateExcelUrlVO>> downloadFile(DownExcelLedgerReqVo reqVo) {
        String downFileType = reqVo.getDownFileType();
        if (StringUtils.isEmpty(downFileType)) {
            throw new AppException("请选择需要下载的文件类型！");
        }
        // 1 pdf下载
        if (downFileType.equals(CommonConstants.PDF)) {
            DownFileTypesResVo resVo = DocumentDownComponent.batchDownPdfFile(reqVo);
            GenerateExcelUrlVO excelUrlVO = new GenerateExcelUrlVO();
            excelUrlVO.setUrl(resVo.getFilePath()).setFileIdentity(downFileType);
            return Result.data(List.of(excelUrlVO));
        }
        // 2 excel下载
        if (downFileType.equals(CommonConstants.EXCEL)) {
            // 1 检查是否下载过 如果已经下载过 直接下载
            String ids = String.join("", reqVo.getIds()) + reqVo.getFileCode();
            if (!reqVo.isAgainGenerate()) {
                SqfwDownFileRecordLog recordLog = downRecordlogService.getUrlByEntityId(ids);
                if (recordLog != null) {
                    List<GenerateExcelUrlVO> urlVOS = new ArrayList<>();
                    GenerateExcelUrlVO g = new GenerateExcelUrlVO();
                    g.setUrl(recordLog.getUrl()).setExcelUrl(recordLog.getUrl()).setFileIdentity(reqVo.getFileCode());
                    urlVOS.add(g);
                    return Result.data(urlVOS);
                }
            }
            // 2 下载数据并上传至云服务器
            List<GenerateExcelUrlVO> urlVOS = summarySafetyCommponent.downExcel1(reqVo);
            urlVOS = CollectionUtil.isEmpty(urlVOS) ? summarySafetyCommponent.downExcel2(reqVo) : urlVOS;
            // 3 记录下载日志
            if (CollectionUtil.isNotEmpty(urlVOS)) {
                GenerateExcelUrlVO excelUrlVO = urlVOS.get(0);
                CommonComponent.insertDownRecordLog(JSONObject.toJSONString(reqVo), JSONObject.toJSONString(Result.data(urlVOS)),reqVo.getFileType(), excelUrlVO.getUrl(), ids);
            }
            return Result.data(urlVOS);
        }
        return Result.success();
    }

    @Override
    public Result<Sqfw_formSummary_new> getSummaryDetail(String summaryId) {
        if (StringUtils.isEmpty(summaryId)) {
            return Result.success();
        }
        Sqfw_formSummary_new summaryNew = this.fetch(summaryId);
        return Result.data(summaryNew);
    }

    @Override
    public Result<?> listByConditionKey(String fillType, String address, String placeName) {
        return summarySafetyCommponent.listByConditionKey(fillType, address, placeName);
    }

    @Override
    public Result<?> listSummaryByPage(SummaryQueryReqVo dto) {
        Cnd cri = Cnd.NEW();
        dto.setCreateId(SecurityUtil.getUserId());
        SqlExpressionGroup expressionGroup = SummarySafetyCommponent.buildQueryExpression(cri, dto);
        // 获取当前时间节点的最后一天
        if (StringUtils.isNotEmpty(dto.getFillDate())) {
            String lastDay = DateUtils.getCurrentDataLastDayStr(dto.getFillDate() + "-01");
            if ("desc".equals(dto.getSort())) {
                expressionGroup.andBetween(Sqfw_formSummary_new::getFillDate, "1970-01-01 00:00:00", lastDay);
            } else {
                expressionGroup.andBetween(Sqfw_formSummary_new::getFillDate, lastDay, new Date());
            }
        }

        // 获取最小月份的数量
        Pagination pagination = this.listPage(dto.getPageNo(), dto.getPageSize(), cri);
        List<Sqfw_formSummary_new> list = pagination.getList(Sqfw_formSummary_new.class);
        if (list.size() == 0) {
            pagination.setTotalCount(0);
            return Result.data(pagination);
        }
        if (StringUtils.isNotEmpty(dto.getFillDate())) {
            int total = summarySafetyCommponent.queryCurrentTotal(list, dto);
            pagination.setTotalCount(total);
        }
        return Result.data(pagination);
    }

    @Override
    public void deleteData(String summaryId) {
        // 1 先删除sumary基础表数据
        Sqfw_formSummary_new summary = this.fetch(summaryId);
        if (summary == null) {
            return;
        }
        String sqfwFlowId = summary.getSqfwFlowId();
        this.delete(summaryId);
        // 2 异步删除其他数据
        CompletableFuture.runAsync(() -> deleteAllData(summaryId, sqfwFlowId));
    }

    @Aop(TransAop.READ_COMMITTED)
    private void deleteAllData(String summaryId, String sqfwFlowId) {
        // 1 先删除文件表数据
        if (StringUtils.isNotEmpty(sqfwFlowId)) {
            Sqfw_completeflow completeflow = sqfwCompleteflowService.fetch(sqfwFlowId);
            if (completeflow != null) {
                sqfwCompleteflowService.delete(completeflow.getId());
            }
        }
        // 删除pdf数据
        List<Sqfw_form_summary_pdf> summaryPdfs = sqfwFormSummaryPdfService.query(Cnd.where(Sqfw_form_summary_pdf::getSummaryId, "=", summaryId));
        if (CollectionUtil.isNotEmpty(summaryPdfs)) {
            sqfwFormSummaryPdfService.delete(summaryPdfs.stream().map(Sqfw_form_summary_pdf::getId).collect(Collectors.toList()));
        }
        List<Sqfw_formSummary_new> formSummaryNews = sqfwFormsummaryNewService.queryByLastSummaryId(List.of(summaryId));
        if (CollectionUtil.isNotEmpty(formSummaryNews)) {
            // 检查提交的数据是大营路的数据
            for (Sqfw_formSummary_new summaryNew : formSummaryNews) {
                boolean dayYingSafeCity = DayingRoadPdfComponent.isDayYingSafeCity(summaryNew.getCreateBy());
                if (dayYingSafeCity) {
                    // 重新构造数据
                    reGeneratePDF(summaryNew.getSqfwFlowId(), CommonConstants.DAYINGROAD);
                }
            }
        }
    }

    @Override
    public Result<Pagination> generateFile(SummaryQueryReqVo reqVo) {
        // 查询数据
        Cnd cri = Cnd.NEW();
        reqVo.setUnitId(SecurityUtil.getUnitId());
        SqlExpressionGroup expressionGroup = SummarySafetyCommponent.buildQueryExpression(cri, reqVo);
        // 按照巡查时间查询
        if (StringUtils.isNotEmpty(reqVo.getFillStartDate())) {
            expressionGroup.andBetween(Sqfw_formSummary_new::getFillDate, reqVo.getFillStartDate() + " 00:00:00", reqVo.getFillEndDate() + " 23:59:59");
        }
        // 查询数据
        List<Sqfw_formSummary_new> formSummarys = this.query(cri);
        // 获取生成材料数据
        List<DownFileTypesResVo> downFileTypesResVos = summarySafetyCommponent.generateFile(formSummarys, reqVo);
        // 组装返回参数
        Pagination p = new Pagination();
        p.setList(downFileTypesResVos);
        p.setTotalCount(formSummarys.size());
        return Result.data(p);
    }

    @Override
    public Result<DownFileTypesResVo> generateDetailFile(SummaryQueryReqVo reqVo) {
        // 查询数据
        Cnd cri = Cnd.NEW();
        reqVo.setUnitId(SecurityUtil.getUnitId());
        SqlExpressionGroup expressionGroup = SummarySafetyCommponent.buildQueryExpression(cri, reqVo);
        // 按照巡查时间查询
        if (StringUtils.isNotEmpty(reqVo.getFillStartDate())) {
            expressionGroup.andBetween(Sqfw_formSummary_new::getFillDate, reqVo.getFillStartDate() + " 00:00:00", reqVo.getFillEndDate() + " 23:59:59");
        }
        // 查询数据
        List<Sqfw_formSummary_new> formSummarys = this.query(cri);
        DownFileTypesResVo downFileTypesResVos = summarySafetyCommponent.generateDetailFile(formSummarys, reqVo);
        return Result.data(downFileTypesResVos);
    }

    @Override
    public Result<DownFileTypesResVo> downTemplate(DownExcelLedgerReqVo reqVo) {
        DownFileTypesResVo downFileTypesResVo =  summarySafetyCommponent.downTemplate(reqVo);
        return Result.data(downFileTypesResVo);
    }

    @Override
    public Sqfw_servicerecord queryCurrentTask(String templateFlag, String type) {
        if (StringUtils.isEmpty(type)) {
            throw new AppException("请传递类型");
        }
        // 大营路比较特殊 第一版开发  所以需要前端传递模板标识
        type = "1".equals(templateFlag) ? "安全排查整治" : type;
        SqfwServicerecordService sqfwServicerecordService = NutzIocUtils.getBean(SqfwServicerecordService.class);
        String customerNeed = SummarySafetyCommponent.getCustomerNeed(templateFlag, type);
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        where.andEquals(Sqfw_servicerecord::getUser_id, SecurityUtil.getUserId())
                .andEquals(Sqfw_servicerecord::getType, type)
                .andEquals(Sqfw_servicerecord::getCustomer_need, customerNeed);
        List<Sqfw_servicerecord> list = sqfwServicerecordService.query(cnd);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Pagination listCurrentTask(SummaryQueryReqVo reqVo) {
        SqfwServicerecordService sqfwServicerecordService = NutzIocUtils.getBean(SqfwServicerecordService.class);
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        where.andEquals(Sqfw_servicerecord::getUser_id, SecurityUtil.getUserId())
                .andEquals(Sqfw_servicerecord::getType, reqVo.getFillType());
        Pagination pagination = sqfwServicerecordService.listPage(reqVo.getPageNo(), reqVo.getPageSize(), cnd);

        int totalCount = pagination.getTotalCount();
        if (totalCount == 0) {
            return pagination;
        }
        List<Sqfw_servicerecord> list = pagination.getList(Sqfw_servicerecord.class);
        return pagination;
    }

    @Override
    public Sqfw_completeflow getCompleteDetail(String completeId) {
        Sqfw_completeflow completeflow = sqfwCompleteflowService.fetch(completeId);
        if (completeflow == null) {
            throw new AppException("数据不存在！");
        }
        // 查询主表信息
        Sqfw_formSummary_new summaryNew = this.fetch(Cnd.where(Sqfw_formSummary_new::getSqfwFlowId, "=", completeId));
        completeflow.setResourceDetailUrl(NutzIocUtils.getOssPrefix() + completeflow.getResourcePath());
        if (summaryNew == null) {
            return completeflow;
        }
        if (SupportBusinessTypeEnum.ONE_TO_FIVE.getName().equals(completeflow.getFileType())) { // 12345
            DownFileTypesResVo resVo = OneFiveComponent.downDocFile(summaryNew, false, FileServiceConfigEnum.OOA);
            completeflow.setWordUrl(resVo.getFilePath());
            return completeflow;
        }
        if (SupportBusinessTypeEnum.FLOOD_CONTROL_ASSISTANT.getName().equals(completeflow.getFileType())) { // 防汛助手
            DownFileTypesResVo resVo = OneFiveComponent.downDocFile(summaryNew, false, FileServiceConfigEnum.OFA);
            completeflow.setWordUrl(resVo.getFilePath());
            return completeflow;
        }
        return completeflow;
    }

    @Override
    public Sqfw_formSummary_new updateSummaryData(TemplateCodeUpdateDTO dto) {
        CompleteFlowCommonPdfService completeFlowCommonPdfService = summarySafetyCommponent.getCompleteFlowCommonPdfService(dto);
        if (completeFlowCommonPdfService == null) {
            throw new BaseException("completeFlowCommonPdfService为空");
        }
        Sqfw_formSummary_new formSummary = dto.getFormSummary();
        if (StringUtils.isEmpty(formSummary.getId())) {
            throw new AppException("数据id不能为空！");
        }
        Sqfw_formSummary_new summaryNew = this.fetch(formSummary.getId());
        if (summaryNew == null) {
            throw new AppException("数据不存在！");
        }
        Sys_user user = CommonComponent.getCurrentUser();
        summaryNew.setUpdateBy(user.getId())
                .setUpdateDate(new Date())
                .setUpdateUserPhone(user.getMobile())
                .setUpdateUserName(user.getUsername())
                .setParamData(formSummary.getParamData());

        this.updateIgnoreNull(summaryNew);
        // 调用重新生成pdf接口实现业务逻辑
        CompleteFlowPdfParamForController param = summarySafetyCommponent.buildSubmitParam(dto);
        param.setCompleteFlowId(summaryNew.getSqfwFlowId());
        completeFlowCommonPdfService.reCreatePdfAndMsg(param);

        // 数据后处理
        lastUpdateSummaryData(summaryNew);
        // 同步更新数据管理
        dataMangeCommunityService.cleanDataBySummaryId(formSummary.getId());
        return dto.getFormSummary();
    }

    @Override
    public Result<Sqfw_formSummary_new> queryCurrentShopLastestData(String shopId, String type) {
        if (StringUtils.isEmpty(shopId)) {
            throw new AppException("请选择商铺！");
        }
        if (StringUtils.isEmpty(type)) {
            throw new AppException("请传递类型[type]！");
        }
        Cnd cnd = Cnd.NEW();
        SqlExpressionGroup where = cnd.where();
        where.andEquals(Sqfw_formSummary_new::getShopsBaseInfoId, shopId)
                .andEquals(Sqfw_formSummary_new::getUnitId, SecurityUtil.getUnitId())
                .andEquals(Sqfw_formSummary_new::getType, type);
        cnd.getOrderBy().desc(Sqfw_formSummary_new::getFillDate);
        cnd.limit(1);
        Sqfw_formSummary_new summaryNew = this.fetch(cnd);
        if (summaryNew != null) {
            summaryNew.setShopsBaseInfo(shopsBaseInfoService.fetch(shopId));
            return Result.data(summaryNew);
        }
        return Result.success();
    }

    private void lastUpdateSummaryData(Sqfw_formSummary_new summaryNew) {
        // 如果是12345 需要重新生成word数据
        if (SupportBusinessTypeEnum.ONE_TO_FIVE.getName().equals(summaryNew.getType())) { // 12345
            OneFiveComponent.downDocFile(summaryNew, true, FileServiceConfigEnum.OOA);
        }
        if (SupportBusinessTypeEnum.FLOOD_CONTROL_ASSISTANT.getName().equals(summaryNew.getType())) { // 防汛助手
            OneFiveComponent.downDocFile(summaryNew, true, FileServiceConfigEnum.OFA);
        }
    }
}


